/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.freedoit.gui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.freedoit.FreeDoitConfig;
import org.freedoit.dao.DAOFactory;
import org.freedoit.om.Project;
import org.freedoit.om.Task;
import org.freedoit.om.TaskType;
import org.freedoit.util.Constants;
import org.freedoit.util.Utils;
import org.jbundle.thin.base.screen.jcalendarbutton.JCalendarPopup;
import org.jbundle.thin.base.screen.jcalendarbutton.JTimePopup;

/**
 *
 * @author wanglei
 */
public class TaskPanel extends javax.swing.JPanel {

    private Task task;
    private java.sql.Date startDate;
    private java.sql.Date dueDate;
    private java.sql.Time startTime;
    private java.sql.Time dueTime;
    /**
     * Creates new form TaskDialog
     */
    public TaskPanel(Task task) {
        assert(task != null);
        this.task = task;
        initComponents();
        specialSetting();
        displayTask();
    }
    
    private void specialSetting() {
        this.jTextAreaTaskDescription.getDocument().addDocumentListener(new DocumentListener () {

            public void insertUpdate(DocumentEvent e) {
                enableJTextAreaTaskDescriptionEdited();
            }

            public void removeUpdate(DocumentEvent e) {
                enableJTextAreaTaskDescriptionEdited();
            }

            public void changedUpdate(DocumentEvent e) {
                enableJTextAreaTaskDescriptionEdited();
            }
            
        });
        this.jTextFieldTaskTag.getDocument().addDocumentListener(new DocumentListener () {

            public void insertUpdate(DocumentEvent e) {
                enableJTextFieldTaskTagEdited();
            }

            public void removeUpdate(DocumentEvent e) {
                enableJTextFieldTaskTagEdited();
            }

            public void changedUpdate(DocumentEvent e) {
                enableJTextFieldTaskTagEdited();
            }
            
        });
    }
    
    private void enableJTextFieldTaskTagEdited() {
        if (!blnJTextFieldTaskTagEdited) {
            blnJTextFieldTaskTagEdited = true;
        }
    }
    
    private void enableJTextAreaTaskDescriptionEdited() {
        if (!blnJTextAreaTaskDescriptionEdited) {
            blnJTextAreaTaskDescriptionEdited = true;
        }
    }
    
    private void displayTask() {
        String strValue = task.getTaskName();
        if (strValue != null && strValue.length() > 0) {
            this.jTextFieldTaskName.setText(strValue);
        }

        strValue = task.getDescription();
        if (strValue != null && strValue.length() > 0) {
            this.jTextAreaTaskDescription.setText(strValue);
            this.blnJTextAreaTaskDescriptionEdited = true;
        }
        
        strValue = task.getTaskTag();
        if (strValue != null && strValue.length() > 0) {
            this.jTextFieldTaskTag.setText(strValue);
            this.blnJTextFieldTaskTagEdited = true;
        }
        
        // Date setting
        displayStartDate(task.getStartDate());
        displayDueDate(task.getDueDate());
        displayStartTime(task.getStartTime());
        displayDueTime(task.getDueTime());
        
        this.jCheckBoxAllDay.setSelected((task.getStartTime() == null) &&
                (task.getDueTime() == null));
        
        // project
        final List<Project> projects = DAOFactory.getProjectDAO().findAll();
        DefaultComboBoxModel dcbm = new DefaultComboBoxModel();
        Long projectId = task.getProjectId();
        int idx = -1;
        int idxSelected = -1;
        if (projects != null) {
            idx ++;
            for (Project p : projects) {
                dcbm.addElement(p);
                if (projectId != null && p.getProjectId().equals(projectId)) {
                    idxSelected = idx;
                }
            }
        }
        this.jComboBoxProject.setModel(dcbm);
        this.jComboBoxProject.setSelectedIndex(idxSelected);
        
        // task type
        final List<TaskType> taskTypes = DAOFactory.getTaskTypeDAO().findAll();
        dcbm = new DefaultComboBoxModel();
        Long taskTypeId = task.getTaskTypeId();
        idx = -1;
        idxSelected = -1;
        if (projects != null) {
            idx ++;
            for (TaskType tt : taskTypes) {
                dcbm.addElement(tt);
                if (taskTypeId != null && tt.getTaskTypeId().equals(taskTypeId)) {
                    idxSelected = idx;
                }
            }
        }
        this.jComboBoxTaskType.setModel(dcbm);
        this.jComboBoxTaskType.setSelectedIndex(idxSelected);
    }
    
    private void displayStartDate(java.sql.Date startDate) {
        this.startDate = startDate;
        if (startDate != null) {
            this.jLabelStartDate.setText(Constants.dateFullSdf.format(this.startDate));
        } else {
            this.jLabelStartDate.setText(FreeDoitConfig.getText("dialog.task.text.start.date"));
        }
    }
    
    private void displayDueDate(java.sql.Date dueDate) {
        this.dueDate = dueDate;
        if (dueDate != null) {
            this.jLabelDueDate.setText(Constants.dateFullSdf.format(this.dueDate));
        } else {
            this.jLabelDueDate.setText(FreeDoitConfig.getText("dialog.task.text.due.date"));
        }
    }
    
    private void displayStartTime(java.sql.Time startTime) {
        this.startTime = startTime;
        if (startTime != null) {
            this.jLabelStartTime.setText(Constants.timeSdf.format(this.startTime));
        } else {
            this.jLabelStartTime.setText("");
        }
    }
    
    private void displayDueTime(java.sql.Time dueTime) {
        this.dueTime = dueTime;
        if (dueTime != null) {
            this.jLabelDueTime.setText(Constants.timeSdf.format(this.dueTime));
        } else {
            this.jLabelDueTime.setText("");
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jTextFieldTaskName = new javax.swing.JTextField();
        jScrollPaneTaskDescription = new javax.swing.JScrollPane();
        jTextAreaTaskDescription = new javax.swing.JTextArea();
        jLabelStartDate = new javax.swing.JLabel();
        jLabelStartTime = new javax.swing.JLabel();
        jLabelTo = new javax.swing.JLabel();
        jLabelDueDate = new javax.swing.JLabel();
        jLabelDueTime = new javax.swing.JLabel();
        jButtonClearDue = new javax.swing.JButton();
        jButtonClearStart = new javax.swing.JButton();
        jComboBoxTaskType = new javax.swing.JComboBox();
        jLabelTaskType = new javax.swing.JLabel();
        jLabelProjects = new javax.swing.JLabel();
        jComboBoxProject = new javax.swing.JComboBox();
        jTextFieldTaskTag = new javax.swing.JTextField();
        jButtonOK = new javax.swing.JButton();
        jButtonCancel = new javax.swing.JButton();
        jCheckBoxAllDay = new javax.swing.JCheckBox();

        jTextFieldTaskName.setFont(FreeDoitConfig.getFont(0, 12));
        jTextFieldTaskName.setText(FreeDoitConfig.getText("dialog.task.text.new.task"));

        jTextAreaTaskDescription.setColumns(20);
        jTextAreaTaskDescription.setFont(FreeDoitConfig.getFont(0, 12));
        jTextAreaTaskDescription.setRows(5);
        jTextAreaTaskDescription.setText(FreeDoitConfig.getText("dialog.task.text.description"));
        jTextAreaTaskDescription.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTextAreaTaskDescriptionMouseClicked(evt);
            }
        });
        jTextAreaTaskDescription.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextAreaTaskDescriptionFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                jTextAreaTaskDescriptionFocusLost(evt);
            }
        });
        jScrollPaneTaskDescription.setViewportView(jTextAreaTaskDescription);

        jLabelStartDate.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelStartDate.setText(FreeDoitConfig.getText("dialog.task.text.start.date"));
        jLabelStartDate.setMaximumSize(new java.awt.Dimension(60, 16));
        jLabelStartDate.setMinimumSize(new java.awt.Dimension(60, 16));
        jLabelStartDate.setName("startDate"); // NOI18N
        jLabelStartDate.setPreferredSize(new java.awt.Dimension(60, 16));
        jLabelStartDate.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelStartDateMouseClicked(evt);
            }
        });

        jLabelStartTime.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelStartTime.setText(" ");
        jLabelStartTime.setMaximumSize(new java.awt.Dimension(6, 16));
        jLabelStartTime.setMinimumSize(new java.awt.Dimension(6, 16));
        jLabelStartTime.setName("startTime"); // NOI18N
        jLabelStartTime.setPreferredSize(new java.awt.Dimension(6, 16));
        jLabelStartTime.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelStartTimeMouseClicked(evt);
            }
        });

        jLabelTo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabelTo.setText("--");

        jLabelDueDate.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelDueDate.setText(FreeDoitConfig.getText("dialog.task.text.due.date"));
        jLabelDueDate.setMaximumSize(new java.awt.Dimension(48, 16));
        jLabelDueDate.setMinimumSize(new java.awt.Dimension(48, 16));
        jLabelDueDate.setName("dueDate"); // NOI18N
        jLabelDueDate.setPreferredSize(new java.awt.Dimension(48, 16));
        jLabelDueDate.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelDueDateMouseClicked(evt);
            }
        });

        jLabelDueTime.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelDueTime.setText(" ");
        jLabelDueTime.setMaximumSize(new java.awt.Dimension(6, 16));
        jLabelDueTime.setMinimumSize(new java.awt.Dimension(6, 16));
        jLabelDueTime.setName("dueTime"); // NOI18N
        jLabelDueTime.setPreferredSize(new java.awt.Dimension(6, 16));
        jLabelDueTime.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelDueTimeMouseClicked(evt);
            }
        });

        jButtonClearDue.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/remove_16.png"))); // NOI18N
        jButtonClearDue.setToolTipText("Clear Due Date and Time");
        jButtonClearDue.setBorder(null);
        jButtonClearDue.setBorderPainted(false);
        jButtonClearDue.setContentAreaFilled(false);
        jButtonClearDue.setIconTextGap(0);
        jButtonClearDue.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonClearDue.setMaximumSize(new java.awt.Dimension(16, 16));
        jButtonClearDue.setMinimumSize(new java.awt.Dimension(16, 16));
        jButtonClearDue.setPreferredSize(new java.awt.Dimension(16, 16));
        jButtonClearDue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonClearDueActionPerformed(evt);
            }
        });

        jButtonClearStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/remove_16.png"))); // NOI18N
        jButtonClearStart.setToolTipText("Clear Start Date and Time");
        jButtonClearStart.setBorder(null);
        jButtonClearStart.setBorderPainted(false);
        jButtonClearStart.setContentAreaFilled(false);
        jButtonClearStart.setIconTextGap(0);
        jButtonClearStart.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonClearStart.setMaximumSize(new java.awt.Dimension(16, 16));
        jButtonClearStart.setMinimumSize(new java.awt.Dimension(16, 16));
        jButtonClearStart.setPreferredSize(new java.awt.Dimension(16, 16));
        jButtonClearStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonClearStartActionPerformed(evt);
            }
        });

        jComboBoxTaskType.setFont(FreeDoitConfig.getFont(0, 12));

        jLabelTaskType.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelTaskType.setText(FreeDoitConfig.getText("dialog.task.label.type"));

        jLabelProjects.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelProjects.setText(FreeDoitConfig.getText("dialog.task.label.project"));

        jComboBoxProject.setFont(FreeDoitConfig.getFont(0, 12));

        jTextFieldTaskTag.setFont(FreeDoitConfig.getFont(0, 12));
        jTextFieldTaskTag.setText(FreeDoitConfig.getText("dialog.task.text.tag"));
        jTextFieldTaskTag.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTextFieldTaskTagMouseClicked(evt);
            }
        });
        jTextFieldTaskTag.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldTaskTagFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                jTextFieldTaskTagFocusLost(evt);
            }
        });

        jButtonOK.setFont(FreeDoitConfig.getFont(0, 12));
        jButtonOK.setText(FreeDoitConfig.getText("dialog.task.button.ok"));
        jButtonOK.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonOKActionPerformed(evt);
            }
        });

        jButtonCancel.setFont(FreeDoitConfig.getFont(0, 12));
        jButtonCancel.setText(FreeDoitConfig.getText("dialog.task.button.cancel"));
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jCheckBoxAllDay.setFont(FreeDoitConfig.getFont(0, 12));
        jCheckBoxAllDay.setText(FreeDoitConfig.getText("dialog.task.checkbox.all.day"));
        jCheckBoxAllDay.setMaximumSize(new java.awt.Dimension(67, 16));
        jCheckBoxAllDay.setMinimumSize(new java.awt.Dimension(67, 16));
        jCheckBoxAllDay.setPreferredSize(new java.awt.Dimension(67, 16));
        jCheckBoxAllDay.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxAllDayActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(160, 160, 160)
                        .addComponent(jButtonOK, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(130, 130, 130)
                        .addComponent(jButtonCancel))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabelTaskType)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jComboBoxTaskType, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabelProjects)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jComboBoxProject, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jTextFieldTaskTag, javax.swing.GroupLayout.DEFAULT_SIZE, 204, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(jScrollPaneTaskDescription, javax.swing.GroupLayout.DEFAULT_SIZE, 576, Short.MAX_VALUE)
                                .addComponent(jTextFieldTaskName))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jButtonClearStart, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(jLabelStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabelStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jLabelTo)
                                .addGap(14, 14, 14)
                                .addComponent(jLabelDueDate, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabelDueTime, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(9, 9, 9)
                                .addComponent(jButtonClearDue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(37, 37, 37)
                                .addComponent(jCheckBoxAllDay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextFieldTaskName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPaneTaskDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jButtonClearStart, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabelStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabelTo)
                            .addComponent(jLabelDueDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButtonClearDue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabelStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabelDueTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(jCheckBoxAllDay, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jComboBoxTaskType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabelTaskType)
                    .addComponent(jLabelProjects)
                    .addComponent(jComboBoxProject, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldTaskTag, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonOK)
                    .addComponent(jButtonCancel))
                .addGap(28, 28, 28))
        );
    }// </editor-fold>

    private void jLabelStartDateMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelStartDateMouseClicked
        // TODO add your handling code here:
        JCalendarPopup popup = JCalendarPopup.createCalendarPopup(
                null, task.getStartDate(), this.jLabelStartDate, null);
        popup.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                
                if (evt.getNewValue() instanceof java.util.Date) {
                    java.util.Date targetDate = (java.util.Date)evt.getNewValue();
                    displayStartDate(new java.sql.Date(targetDate.getTime()));
                }
            }
            
        });
    }//GEN-LAST:event_jLabelStartDateMouseClicked

    private void jLabelStartTimeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelStartTimeMouseClicked
        // TODO add your handling code here:
        JTimePopup popup = JTimePopup.createTimePopup(
                null, task.getStartTime(), this.jLabelStartTime, null);
        popup.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                
                if (evt.getNewValue() instanceof java.util.Date) {
                    java.util.Date targetDate = (java.util.Date)evt.getNewValue();
                    displayStartTime(new java.sql.Time(targetDate.getTime()));
                }
            }
            
        });
    }//GEN-LAST:event_jLabelStartTimeMouseClicked

    private void jLabelDueDateMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelDueDateMouseClicked
        // TODO add your handling code here:
        JCalendarPopup popup = JCalendarPopup.createCalendarPopup(
                null, task.getDueDate(), this.jLabelDueDate, null);
        popup.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                
                if (evt.getNewValue() instanceof java.util.Date) {
                    java.util.Date targetDate = (java.util.Date)evt.getNewValue();
                    displayDueDate(new java.sql.Date(targetDate.getTime()));
                }
            }
            
        });
    }//GEN-LAST:event_jLabelDueDateMouseClicked

    private void jLabelDueTimeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelDueTimeMouseClicked
        // TODO add your handling code here:
        JTimePopup popup = JTimePopup.createTimePopup(
                null, task.getDueTime(), this.jLabelDueTime, null);
        popup.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                
                if (evt.getNewValue() instanceof java.util.Date) {
                    java.util.Date targetDate = (java.util.Date)evt.getNewValue();
                    displayDueTime(new java.sql.Time(targetDate.getTime()));
                }
            }
            
        });
    }//GEN-LAST:event_jLabelDueTimeMouseClicked

    private void jTextAreaTaskDescriptionMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTextAreaTaskDescriptionMouseClicked
        // TODO add your handling code here:
        if (!blnJTextAreaTaskDescriptionEdited) {
            this.jTextAreaTaskDescription.setText("");
        }
    }//GEN-LAST:event_jTextAreaTaskDescriptionMouseClicked

    private void jTextFieldTaskTagFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldTaskTagFocusGained
        // TODO add your handling code here:
        if (!blnJTextFieldTaskTagEdited) {
            blnJTextFieldTaskTagEdited = true; // will not fire the document change action
            this.jTextFieldTaskTag.setText("");
            blnJTextFieldTaskTagEdited = false;
        }
    }//GEN-LAST:event_jTextFieldTaskTagFocusGained

    private void jButtonClearStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonClearStartActionPerformed
        // TODO add your handling code here:
        this.displayStartDate(null);
        this.displayStartTime(null);
    }//GEN-LAST:event_jButtonClearStartActionPerformed

    private void jButtonClearDueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonClearDueActionPerformed
        // TODO add your handling code here:
        this.displayDueDate(null);
        this.displayDueTime(null);
    }//GEN-LAST:event_jButtonClearDueActionPerformed

    private boolean checkBeforeOK() {
        java.sql.Time startTimeChk = this.startTime;
        java.sql.Time dueTimeChk = this.dueTime;
        if (this.jCheckBoxAllDay.isSelected()) {
            startTimeChk = null;
            dueTimeChk = null;
        }
        String strValue = this.jTextFieldTaskName.getText();
        if (strValue == null || "".equals(strValue.trim())) {
            JOptionPane.showMessageDialog(this, "Task Name cannot be empty or space", "Error", JOptionPane.ERROR_MESSAGE);
            jTextFieldTaskName.setFocusable(true);
            return false;
        }
        
        // time is not null but date is null
        if (startTimeChk != null && startDate == null) {
            JOptionPane.showMessageDialog(this, "Start date cannot be empty while start time exists", "Error", JOptionPane.ERROR_MESSAGE);
            this.jLabelStartDate.setFocusable(true);
            return false;
        }
        
        if (dueTimeChk != null && dueDate == null) {
            JOptionPane.showMessageDialog(this, "Due date cannot be empty while due time exists", "Error", JOptionPane.ERROR_MESSAGE);
            this.jLabelDueDate.setFocusable(true);
            return false;
        }
        
        // start date is empty but due date exists
        if (dueDate != null && startDate == null) {
            JOptionPane.showMessageDialog(this, "Start date cannot be empty while due date exists", "Error", JOptionPane.ERROR_MESSAGE);
            this.jLabelStartDate.setFocusable(true);
            return false;
        }

        // due date and time must be after start date and time
        if (dueDate != null && startDate != null) {
            int cmp = Utils.compareSQLDate(dueDate, startDate);
            if (cmp < 0) {
                JOptionPane.showMessageDialog(this, "Due date cannot be before start date", "Error", JOptionPane.ERROR_MESSAGE);
                this.jLabelDueDate.setFocusable(true);
                return false;
            } else if (cmp == 0) {
                if (dueTimeChk == null) {
                    JOptionPane.showMessageDialog(this, "Due date and time must be after start date and time", "Error", JOptionPane.ERROR_MESSAGE);
                } else {
                    if (startTimeChk != null && Utils.compareSQLTime(startTimeChk, dueTimeChk) >= 0) {
                        JOptionPane.showMessageDialog(this, "Due date and time must be after start date and time", "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            } else {
                // OK
            }
        }
        
        return true;
    }

    private void fillTaskValue() {
        // TODO
        // Task Name
        task.setTaskName(this.jTextFieldTaskName.getText());
        
        // Task Description
        if (this.blnJTextAreaTaskDescriptionEdited) {
            task.setDescription(this.jTextAreaTaskDescription.getText());
        }
        
        // Task Tag
        if (this.blnJTextFieldTaskTagEdited) {
            task.setTaskTag(this.jTextFieldTaskTag.getText());
        }
        
        // start and due date and time
        task.setStartDate(startDate);
        task.setDueDate(dueDate);
        task.setStartTime(startTime);
        task.setDueTime(dueTime);
        
        // task type
        Object o = this.jComboBoxTaskType.getSelectedItem();
        if (o instanceof TaskType) {
            TaskType tt = (TaskType)o;
            task.setTaskTypeId(tt.getTaskTypeId());
        }
        
        // project
        o = this.jComboBoxProject.getSelectedItem();
        if (o instanceof Project) {
            Project p = (Project)o;
            task.setProjectId(p.getProjectId());
        }
    }
    private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed
        // TODO add your handling code here:
        if (checkBeforeOK()) {
            if (this.jCheckBoxAllDay.isSelected()) {
                this.startTime = null;
                this.dueTime = null;
            }
            fillTaskValue();
            this.blnOKClicked = true;
            //exitDialog(this);
        }
    }//GEN-LAST:event_jButtonOKActionPerformed

    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
        // TODO add your handling code here:
        //exitDialog(this);
    }//GEN-LAST:event_jButtonCancelActionPerformed

    private void jTextAreaTaskDescriptionFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextAreaTaskDescriptionFocusGained
        // TODO add your handling code here:
        if (!blnJTextAreaTaskDescriptionEdited) {
            blnJTextAreaTaskDescriptionEdited = true; // will not fire the document change action
            this.jTextAreaTaskDescription.setText("");
            blnJTextAreaTaskDescriptionEdited = false;
        }
    }//GEN-LAST:event_jTextAreaTaskDescriptionFocusGained

    private void jTextAreaTaskDescriptionFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextAreaTaskDescriptionFocusLost
        // TODO add your handling code here:
        if (!blnJTextAreaTaskDescriptionEdited) {
            blnJTextAreaTaskDescriptionEdited = true; // will not fire the document change action
            this.jTextAreaTaskDescription.setText(FreeDoitConfig.getText("dialog.task.text.description"));
            blnJTextAreaTaskDescriptionEdited = false;
        }
    }//GEN-LAST:event_jTextAreaTaskDescriptionFocusLost

    private void jTextFieldTaskTagFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldTaskTagFocusLost
        // TODO add your handling code here:
        if (!blnJTextFieldTaskTagEdited) {
            blnJTextFieldTaskTagEdited = true; // will not fire the document change action
            this.jTextFieldTaskTag.setText(FreeDoitConfig.getText("dialog.task.text.tag"));
            blnJTextFieldTaskTagEdited = false;
        }
    }//GEN-LAST:event_jTextFieldTaskTagFocusLost

    private void jTextFieldTaskTagMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTextFieldTaskTagMouseClicked
        // TODO add your handling code here:
        if (!blnJTextFieldTaskTagEdited) {
            blnJTextFieldTaskTagEdited = true; // will not fire the document change action
            this.jTextFieldTaskTag.setText("");
            blnJTextFieldTaskTagEdited = false;
        }
    }//GEN-LAST:event_jTextFieldTaskTagMouseClicked

    private void jCheckBoxAllDayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxAllDayActionPerformed
        // TODO add your handling code here:
        if (this.jCheckBoxAllDay.isSelected()) {
            this.jLabelStartTime.setText("");
            this.jLabelStartTime.setEnabled(false);
            this.jLabelDueTime.setText("");
            this.jLabelDueTime.setEnabled(false);
        } else {
            this.jLabelStartTime.setEnabled(true);
            if (this.startTime == null) {
                this.startTime = Utils.getNextTimePointFromNow();
            }
            this.displayStartTime(this.startTime);

            this.jLabelDueTime.setEnabled(true);
            if (this.dueTime == null) {
                this.dueTime = Utils.getNextTimePoint(this.startTime);
            }
            this.displayDueTime(this.dueTime);
        }
    }//GEN-LAST:event_jCheckBoxAllDayActionPerformed

    public boolean isOKClicked() {
        return this.blnOKClicked;
    }
    
    private boolean blnJTextAreaTaskDescriptionEdited;
    private boolean blnJTextFieldTaskTagEdited;
    
    private boolean blnOKClicked = false;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JButton jButtonClearDue;
    private javax.swing.JButton jButtonClearStart;
    private javax.swing.JButton jButtonOK;
    private javax.swing.JCheckBox jCheckBoxAllDay;
    private javax.swing.JComboBox jComboBoxProject;
    private javax.swing.JComboBox jComboBoxTaskType;
    private javax.swing.JLabel jLabelDueDate;
    private javax.swing.JLabel jLabelDueTime;
    private javax.swing.JLabel jLabelProjects;
    private javax.swing.JLabel jLabelStartDate;
    private javax.swing.JLabel jLabelStartTime;
    private javax.swing.JLabel jLabelTaskType;
    private javax.swing.JLabel jLabelTo;
    private javax.swing.JScrollPane jScrollPaneTaskDescription;
    private javax.swing.JTextArea jTextAreaTaskDescription;
    private javax.swing.JTextField jTextFieldTaskName;
    private javax.swing.JTextField jTextFieldTaskTag;
    // End of variables declaration//GEN-END:variables
}
